package main

import (
	"fmt"
	"log"
	"sync"
	"time"

	"golang.org/x/sync/singleflight"
)

var (
	sfGroup = &singleflight.Group{}
	dbSim   = make(map[string]string)
)

// 模拟耗时数据库查询
func queryDB(key string) (string, error) {
	log.Printf("Querying DB for key: %s", key)
	time.Sleep(100 * time.Millisecond) // 模拟延迟
	return "result_from_db_" + key, nil
}

// 获取数据（带 singleflight 防重）
func getData(key string) (string, error) {
	result, err, _ := sfGroup.Do(key, func() (interface{}, error) {
		// 先查缓存（这里省略真实缓存，仅演示逻辑）
		if val, ok := dbSim[key]; ok {
			return val, nil
		}
		// 缓存未命中，查数据库
		val, err := queryDB(key)
		if err == nil {
			dbSim[key] = val // 写入缓存（简化版）
		}
		return val, err
	})
	return result.(string), err
}

func main() {
	var wg sync.WaitGroup
	keys := []string{"user:123", "user:123", "user:123"} // 多个相同 key 请求

	for _, k := range keys {
		wg.Add(1)
		go func(key string) {
			defer wg.Done()
			res, err := getData(key)
			if err != nil {
				log.Printf("Error: %v", err)
			} else {
				fmt.Printf("Got: %s\n", res)
			}
		}(k)
	}

	wg.Wait()
}
